﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
using System.Windows;
using System.Linq;
using OfficeOpenXml;
using System.Collections.Concurrent;

namespace ToolExcelPub
{
    public static partial class XTool
    {
        // 表里ID反向枚举
        public static ConcurrentDictionary<string, Dictionary<string, string>> CDictDictEnum2 = new ConcurrentDictionary<string, Dictionary<string, string>>();
        // 表内枚举
        public static ConcurrentDictionary<string, Dictionary<string, string>> CDictDictEnum3 = new ConcurrentDictionary<string, Dictionary<string, string>>();
        // 表格页
        public static ConcurrentDictionary<string, XPageInfo> CDictPages = new ConcurrentDictionary<string, XPageInfo>();
        public static void ReadPages()
        {
            ShowInfo("ReadPages!");

            CDictDictEnum2.Clear();
            CDictPages.Clear();
            DictFilePages.Clear();

            foreach (var item in DictXFileInfo.Values)
            {
                ReadPage(item);
            }

            DictDictEnumPageId = (from it in CDictDictEnum2 orderby it.Key ascending select it).ToDictionary(it => it.Key, it => it.Value);
            DictDictEnumPage = (from it in CDictDictEnum3 orderby it.Key ascending select it).ToDictionary(it => it.Key, it => it.Value);
            DictPages = (from it in CDictPages orderby it.Key ascending select it).ToDictionary(it => it.Key, it => it.Value);
        }
        public static void ReadPage(XFileInfo fileinfo)
        {
            if (fileinfo.HasType(EToolFileType.枚举)
                || fileinfo.HasType(EToolFileType.公共类))
            {
                return;
            }
            if (!fileinfo.NeedRead)
            {
                return;
            }
            string path_excel = fileinfo.FileName;

            if (File.Exists(path_excel))
            {
                var excelPathFileInfo = new FileInfo(path_excel);
                using (var package = new ExcelPackage(excelPathFileInfo))
                {
                    var wk = package.Workbook;
                    foreach (var sheet in wk.Worksheets)
                    {
                        string sheetName = sheet.Name;
                        // 无效页
                        if (sheetName[0] == '~')
                        {
                            continue;
                        }

                        // 表内枚举页
                        if (sheetName.StartsWith("PageEnums"))
                        {
                            var rows = sheet.Dimension.End.Row;
                            var enumcols = sheet.Dimension.End.Column;

                            for (int j = 1; (j + 2) <= enumcols; j += 3)
                            {
                                //枚举名
                                string DictKey = "";
                                var celldictk = sheet.GetValue(2, j);
                                if (celldictk != null)
                                {
                                    DictKey = celldictk.ToString();
                                }
                                if (string.IsNullOrEmpty(DictKey))
                                {
                                    break;
                                }
                                //枚举注释
                                string DictKeyDesc = "";
                                var celldictkd = sheet.GetValue(1, j);
                                if (celldictkd != null)
                                {
                                    DictKeyDesc = celldictkd.ToString();
                                }
                                if (string.IsNullOrEmpty(DictKey))
                                {
                                    DictKeyDesc = "";
                                }
                                Dictionary<string, string> DictList = new Dictionary<string, string>();
                                for (int i = 4; i <= rows; i++)
                                {
                                    var cell1 = sheet.GetValue(i, j);
                                    var cell2 = sheet.GetValue(i, j + 1);
                                    if (cell1 == null || cell2 == null)
                                    {
                                        continue;
                                    }
                                    string enumK = cell2.ToString();
                                    string enumV = cell1.ToString();
                                    if (enumK == "" || enumV == "")
                                    {
                                        continue;
                                    }
                                    if (DictList.ContainsKey(enumK))
                                    {
                                        ShowError($"重复的枚举表Key {DictKey} {enumK}", "提示");
                                        continue;
                                    }
                                    if (DictList.ContainsKey(enumV))
                                    {
                                        ShowError($"重复的枚举表Value {DictKey} {enumV}", "提示");
                                        continue;
                                    }
                                    DictList[enumK] = enumV;
                                }
                                if (CDictDictEnum3.ContainsKey(DictKey))
                                {
                                    ShowError($"重复的枚举表类型 {DictKey}", "提示");
                                }
                                else
                                {
                                    CDictDictEnum3[DictKey] = DictList;
                                    DictDictEnumPubDesc[DictKey] = DictKeyDesc;
                                }
                            }
                            continue;
                        }

                        string[] nodes = sheetName.Split(new string[] { "|" }, StringSplitOptions.RemoveEmptyEntries);

                        bool 导出枚举 = false;
                        string pagename = sheet.Name;
                        string pagenamecn = sheet.Name;
                        if (nodes.Length >= 2)
                        {
                            pagename = nodes[1];
                            pagenamecn = nodes[0];
                            if (pagenamecn[0] == 'e' || pagenamecn[0] == 'E')
                            {
                                导出枚举 = true;
                            }
                        }

                        bool newpage = true;
                        if (CDictPages.TryGetValue(pagename, out var page))
                        {
                            newpage = false;
                        }
                        else
                        {
                            page = new XPageInfo(pagename);
                        }
                        var NameFile = Path.GetFileName(path_excel);
                        page.NameCn += $"{pagenamecn} ";
                        page.NameFile += $"{NameFile} ";
                        page.ValidType = fileinfo.ToolType;

                        var pagerows = sheet.Dimension.End.Row;
                        var pagecols = sheet.Dimension.End.Column;
                        if (pagerows < 5 || pagecols <= 0)
                        {
                            continue;
                        }

                        if (newpage)
                        {
                            for (int k = 1; k <= pagecols; k++)
                            {
                                //列名中文
                                {
                                    var cell = sheet.GetValue(2, k);
                                    if (cell != null)
                                    {
                                        page.HeadC.Add(cell.ToString());
                                    }
                                    else
                                    {
                                        page.HeadC.Add("");
                                    }
                                }
                                //列名英文
                                {
                                    var cell = sheet.GetValue(3, k);
                                    if (cell != null)
                                    {
                                        string strheadenum = cell.ToString();
                                        string[] strheadenumnodes = strheadenum.Split(new string[] { "|" }, StringSplitOptions.RemoveEmptyEntries);
                                        if (strheadenumnodes.Length >= 2)
                                        {
                                            page.Head.Add(strheadenumnodes[0]);
                                            page.HeadEnum.Add(strheadenumnodes[1]);
                                        }
                                        else
                                        {
                                            page.Head.Add(strheadenum);
                                            page.HeadEnum.Add(strheadenum);
                                        }
                                    }
                                    else
                                    {
                                        page.Head.Add("");
                                        page.HeadEnum.Add("");
                                    }
                                }
                                //客户端类型
                                {
                                    var tpClient = "";
                                    var cell = sheet.GetValue(4, k);
                                    if (cell != null)
                                    {
                                        tpClient = cell.ToString();
                                        if (tpClient == "float")
                                        {
                                            tpClient = "double";
                                        }
                                        if (tpClient == "List<float>")
                                        {
                                            tpClient = "List<double>";
                                        }
                                        //if (DictXPclassInfo.ContainsKey(tpClient))
                                        //{
                                        //    tpClient = $"List<{tpClient}>";
                                        //}
                                    }
                                    page.TypeClient.Add(tpClient);
                                }
                                //服务器类型
                                {
                                    var tpServer = "";
                                    var cell = sheet.GetValue(5, k);
                                    if (cell != null)
                                    {
                                        tpServer = cell.ToString();
                                        //if (DictXPclassInfo.ContainsKey(tpServer))
                                        //{
                                        //    tpServer = $"List<{tpServer}>";
                                        //}
                                    }
                                    page.TypeServer.Add(tpServer);
                                }
                            }

                            if (导出枚举)
                            {
                                string DictKey = "EnumAAA";
                                var cell = sheet.GetValue(3, 1);
                                if (cell != null)
                                {
                                    DictKey = (string)cell;
                                }
                                else
                                {
                                    page.Head.Add("");
                                    page.HeadEnum.Add("");
                                }

                                int j = 1;
                                Dictionary<string, string> DictList = new Dictionary<string, string>();
                                for (int i = 6; i <= pagerows; i++)
                                {
                                    var cell1 = sheet.GetValue(i, j);
                                    var cell2 = sheet.GetValue(i, j + 1);
                                    if (cell1 == null || cell2 == null)
                                    {
                                        continue;
                                    }
                                    string enumK = cell2.ToString();
                                    string enumV = cell1.ToString();
                                    if (enumK == "" || enumV == "")
                                    {
                                        continue;
                                    }
                                    if (DictList.ContainsKey(enumK))
                                    {
                                        ShowError($"重复的枚举表Key {DictKey} {enumK}", "提示");
                                        continue;
                                    }
                                    if (DictList.ContainsKey(enumV))
                                    {
                                        ShowError($"重复的枚举表Value {DictKey} {enumV}", "提示");
                                        continue;
                                    }
                                    DictList[enumK] = enumV;
                                }
                                if (CDictDictEnum2.ContainsKey(DictKey))
                                {
                                    ShowError($"重复的枚举表类型 {DictKey}", "提示");
                                }
                                else
                                {
                                    CDictDictEnum2[DictKey] = DictList;
                                }
                            }
                        }

                        //导出表数据
                        for (int j = 6; j <= pagerows; j++)
                        {
                            var cellfirst = sheet.GetValue(j, 1);
                            if (cellfirst == null)
                            {
                                continue;
                            }
                            if (string.IsNullOrEmpty(cellfirst.ToString()))
                            {
                                continue;
                            }
                            var listrowvalue = new List<string>();
                            for (int k = 0; k < page.Head.Count ; k++)
                            {
                                string s_value = "";
                                var cell = sheet.GetValue(j, k + 1);
                                if (cell != null)
                                {
                                    s_value = cell.ToString();
                                }
                                if (string.IsNullOrEmpty(s_value))
                                {
                                    var type1 = page.TypeClient[k];
                                    var type2 = page.TypeServer[k];
                                    bool isnumber = (type1 == "int" || type1 == "long" || type1 == "float" || type1 == "double")
                                        || (type2 == "int" || type2 == "long" || type2 == "float" || type2 == "double");
                                    bool isbool = type1 == "bool" || type2 == "bool";
                                    if (isnumber)
                                    {
                                        s_value = "0";
                                    }
                                    if (isbool)
                                    {
                                        s_value = "false";
                                    }
                                }

                                // 已经移动到导出数据时查询处理
                                //if (!string.IsNullOrEmpty(page.HeadEnum[k]))
                                //{
                                //    if (DictDictEnumPub.TryGetValue(page.HeadEnum[k], out var DictList1))
                                //    {
                                //        if (DictList1.ContainsKey(s_value))
                                //        {
                                //            s_value = DictList1[s_value];
                                //        }
                                //    }
                                //    if (DictDictEnumPage.TryGetValue(page.HeadEnum[k], out var DictList2))
                                //    {
                                //        if (DictList2.ContainsKey(s_value))
                                //        {
                                //            s_value = DictList2[s_value];
                                //        }
                                //    }
                                //}
                                listrowvalue.Add(s_value);
                            }
                            page.ListValue.Add(listrowvalue);
                        }
                        if (page.IsLegal())
                        {
                            CDictPages[page.Name] = page;

                            if (!DictFilePages.TryGetValue(NameFile, out var filepages))
                            {
                                filepages = new List<string>();
                                DictFilePages[NameFile] = filepages;
                            }
                            filepages.Add(page.Name);
                        }

                    }
                }

            }
        }
        public class XPageInfo
        {
            public string Name = "";
            public string NameCn = "";
            public string NameFile = "";
            public EToolFileType ValidType = EToolFileType.公共;
            public List<string> HeadC;
            public List<string> Head;
            public List<string> HeadEnum;
            public List<string> TypeClient;
            public List<string> TypeServer;
            public List<List<string>> ListValue;

            public XPageInfo(string name)
            {
                Name = name;
                ValidType = EToolFileType.公共;

                HeadC = new List<string>();
                Head = new List<string>();
                HeadEnum = new List<string>();
                TypeClient = new List<string>();
                TypeServer = new List<string>();
                ListValue = new List<List<string>>();
            }
            public bool IsLegal()
            {
                if (Head.Count <= 0)
                {
                    return false;
                }
                if (ListValue.Count <= 0)
                {
                    return false;
                }
                return true;
            }
            public bool HasType(EToolFileType type)
            {
                return (ValidType & type) > 0;
            }

        }
    }

}
